package com.chcit.mobile.app.utils;

//FTPCommunication类
// 实现FTP通信.包括FTP服务器连接,读取文件列表,切换目录.上传文件.
// 实现回调函数,提示上层请求完成.
import com.elvishew.xlog.XLog;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import static java.lang.Thread.sleep;

public class FTPUtils {

    //ftp服务器地址
    private String hostname = "";
    //ftp服务器端口号默认为21
    private Integer port = 21;
    //ftp登录账号
    private String username = "";
    //ftp登录密码
    private String password = "";
    //超时时间
    public int timeOut = 2;
    //被动模式开关 如果不开被动模式 有防火墙 可能会上传失败， 但被动模式需要ftp支持
    public boolean enterLocalPassiveMode = false;

    private FTPClient ftpClient = null;

    private static FTPUtils mFTPUtils = null;

    private String filePath;


    private FTPUtils() {


    }
    public void initFTP(String url){
        String regex = "^ftp://(\\S+)([@])(\\S+)[:](\\d+)[/](\\S+)";
        Pattern p=Pattern.compile(regex);
        Matcher m=p.matcher(url);
        while(m.find()){
            mFTPUtils.hostname = m.group(3);
            mFTPUtils.port =   Integer.valueOf(m.group(4));
            String[] userNameAndPasswords =  m.group(1).split(":");
            mFTPUtils.username = userNameAndPasswords[0];
            mFTPUtils.password = userNameAndPasswords[1];
            mFTPUtils.ftpClient =connectFtpServer(mFTPUtils.hostname,mFTPUtils.port,mFTPUtils.username,mFTPUtils.password,"utf-8");

        }
    }
    public static FTPUtils getInstance() {
        if (mFTPUtils == null) {
            synchronized (FTPUtils.class) {
                if (mFTPUtils == null) {
                    mFTPUtils = new FTPUtils();
                }
            }

        }
        return mFTPUtils;
    }
   public OutputStream getFileInputStream(String url){
       try {
           String regex = "^ftp://(\\S+)([@])(\\S+)[:](\\d+)([/]\\S+)$";
           Pattern p = Pattern.compile(regex);
           Matcher m = p.matcher(url);
           //第一次进来,将上传路径设置成相对路径

           ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
           //切换FTP目录
           //changeWorkingDirectory(m.group(5));
           if(m.find()){
               String filename = m.group(5);
//               FTPFile[] ftpFiles = ftpClient.listFiles(filename);
               //ftpClient.appendFileStream()
               return  ftpClient.appendFileStream(filename);
           }

       }catch (Exception e){
           e.printStackTrace();
       }
       return null;

   }

    /**
     * 连接 FTP 服务器
     *
     * @param addr     FTP 服务器 IP 地址
     * @param port     FTP 服务器端口号
     * @param username 登录用户名
     * @param password 登录密码
     * @return
     * @throws Exception
     */
    public static FTPClient connectFtpServer(String addr, int port, String username, String password, String controlEncoding) {
        FTPClient ftpClient = new FTPClient();

        try {
            /**设置文件传输的编码*/
            ftpClient.setControlEncoding(controlEncoding);

            /**连接 FTP 服务器
             * 如果连接失败，则此时抛出异常，如ftp服务器服务关闭时，抛出异常：
             * java.net.ConnectException: Connection refused: connect*/
            ftpClient.connect(addr, port);
            /**登录 FTP 服务器
             * 1）如果传入的账号为空，则使用匿名登录，此时账号使用 "Anonymous"，密码为空即可*/
            if (StringUtils.isBlank(username)) {
                ftpClient.login("Anonymous", "");
            } else {
                ftpClient.login(username, password);
            }

            /** 设置传输的文件类型
             * BINARY_FILE_TYPE：二进制文件类型
             * ASCII_FILE_TYPE：ASCII传输方式，这是默认的方式
             * ....
             */
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

            /**
             * 确认应答状态码是否正确完成响应
             * 凡是 2开头的 isPositiveCompletion 都会返回 true，因为它底层判断是：
             * return (reply >= 200 && reply < 300);
             */
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                /**
                 * 如果 FTP 服务器响应错误 中断传输、断开连接
                 * abort：中断文件正在进行的文件传输，成功时返回 true,否则返回 false
                 * disconnect：断开与服务器的连接，并恢复默认参数值
                 */
                ftpClient.abort();
                ftpClient.disconnect();
            } else {
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println(">>>>>FTP服务器连接登录失败，请检查连接参数是否正确，或者网络是否通畅*********");
        }
        return ftpClient;
    }
   public  void  closeFTPConnect(){
        closeFTPConnect(mFTPUtils.ftpClient);
   }
    /**
     * 使用完毕，应该及时关闭连接
     * 终止 ftp 传输
     * 断开 ftp 连接
     *
     * @param ftpClient
     * @return
     */
    public static FTPClient closeFTPConnect(FTPClient ftpClient) {
        try {
            if (ftpClient != null && ftpClient.isConnected()) {
                ftpClient.abort();
                ftpClient.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ftpClient;
    }
    //改变目录路径
    public boolean changeWorkingDirectory(String directory) {
        boolean flag = true;
        try {
            flag = ftpClient.changeWorkingDirectory(directory);
            if (!flag) {
                XLog.e( "所在的目录 : " + ftpClient.printWorkingDirectory() + " 进入下一级 " + directory + " 目录失败");
            } else {
                XLog.e("FTP","进入目录成功，当前所在目录 :" + ftpClient.printWorkingDirectory());
            }
        } catch (IOException ioe) {
            XLog.e(ioe.getMessage(), ioe+"");
        }
        return flag;
    }

    /**
     * 下载文件 *
     *
     * @param pathname  FTP服务器文件目录 *
     * @param filename  文件名称 *
     * @param localpath 下载后的文件路径 *
     * @return
     */
    public boolean downloadFile(String pathname, String filename, String localpath) {
        boolean flag = false;
        OutputStream os = null;
        try {
            //第一次进来,将上传路径设置成相对路径
            if (pathname.startsWith("/")) {
                pathname = pathname.substring(1);
            }

            ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
            //切换FTP目录
            changeWorkingDirectory(pathname);
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                if (filename.equalsIgnoreCase(file.getName())) {
                    File localFile = new File(localpath + "/" + file.getName());
                    os = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(file.getName(), os);
                    os.close();
                }
            }
            ftpClient.logout();
            flag = true;
        } catch (Exception e) {
            XLog.e(e.getMessage(), e+"");
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    XLog.e(e.getMessage(), e+"");
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    XLog.e(e.getMessage(), e+"");
                }
            }
        }
        return flag;
    }


}